<template>
  <div class="flex flex-col h-full w-full">
    <vxe-card title="" class="w-full" :border="false">
      <AuForm ref="formRef" :formList="formList" @submit="search" />
    </vxe-card>

    <div class="flex-grow w-full overflow-hidden mt-[16px]">
      <AuTable ref="tableRef" v-bind="gridOption" @actionClick="actionClick">
        <template #status_default="{ row }">
          <el-tag :type="formatStatusText(row).status">
            {{ t(formatStatusText(row).text) }}
          </el-tag>
        </template>

        <template #version_default="{ row }">
          {{ row.deviceFormulaUseRecord?.name }}
        </template>
        <template #isUpdate_default="{ row }">
          <el-tag :type="updateHandle(row).status">
            {{ t(updateHandle(row).text) }}
          </el-tag>
        </template>
      </AuTable>
    </div>

    <!--    移机弹窗-->
    <AuModal
      v-model="showMovePopup"
      :title="t('device_manage.form.telRelocation')"
      :width="584"
      :padding="false"
      @handleConfirm="handleMoveConfirm"
      @close="closeMove"
    >
      <div class="flex flex-col pt-[30px] pb-[16px] px-[30px]">
        <el-descriptions
          :title="t('device_manage.form.original_store_info')"
          direction="vertical"
        >
          <template #title>
            <div class="flex items-center">
              <div class="w-[2px] h-[14px] bg-[--el-color-primary]" />
              <div class="text-[14px] ml-[8px]">
                {{ t("device_manage.form.original_store_info") }}
              </div>
            </div>
          </template>
          <el-descriptions-item>
            <template #label>
              <span class="text-[#666B71]">{{
                t("device_manage.form.original_store")
              }}</span>
            </template>
            <span class="text-[--autata-font-color]">{{
              rowData.store_name
            }}</span>
          </el-descriptions-item>
          <el-descriptions-item>
            <template #label>
              <span class="text-[#666B71]">{{
                t("device_manage.form.operator")
              }}</span>
            </template>
            <span class="text-[--autata-font-color]">{{
              rowData.operator
            }}</span>
          </el-descriptions-item>
        </el-descriptions>
        <el-descriptions class="mt-[14px]">
          <template #title>
            <div class="flex items-center">
              <div class="w-[2px] h-[14px] bg-[--el-color-primary]" />
              <div class="text-[14px] ml-[8px]">
                {{ t("device_manage.form.new_store_info") }}
              </div>
            </div>
          </template>
          <el-descriptions-item>
            <template #label>
              <span class="text-[#666B71]">{{
                t("device_manage.form.region")
              }}</span>
            </template>
            <el-cascader
              v-model="formMoveData.groupId"
              :options="groupOptions"
              v-bind="cascadeProps"
              :placeholder="t('device_manage.form.select_region')"
              style="width: 190px"
              @change="handleMoveChange"
            />
          </el-descriptions-item>
          <el-descriptions-item>
            <template #label>
              <span class="text-[#666B71]">{{
                t("device_manage.form.new_store")
              }}</span>
            </template>
            <el-select
              v-model="formMoveData.store_id"
              :placeholder="t('device_manage.form.select_operator')"
              :filterable="true"
              style="width: 190px"
            >
              <el-option
                v-for="item in storeList"
                :key="item.id"
                :label="item.name"
                :value="item.id"
              />
            </el-select>
          </el-descriptions-item>
        </el-descriptions>
      </div>
    </AuModal>

    <!--    激活弹窗-->
    <AuModal
      v-model="showAcPopup"
      :title="t('device_manage.form.activate_device')"
      :width="460"
      :padding="false"
      @handleConfirm="handleAcConfirm"
      @close="closeAc"
    >
      <div class="px-[20px] py-[30px] active-wrap">
        <el-form
          ref="formAcRef"
          :model="formAcData"
          :rules="formAcRule"
          class="formula-inForm"
          label-width="120px"
        >
          <el-form-item :label="t('device_manage.form.region')" prop="group_id">
            <el-cascader
              v-model="formAcData.group_id"
              :options="groupOptions"
              v-bind="cascadeProps"
              :placeholder="t('device_manage.form.select_region')"
              style="width: 200px"
              @change="handleMoveChange"
            />
          </el-form-item>
          <el-form-item
            :label="t('device_manage.form.store_name')"
            prop="store_id"
          >
            <el-select
              v-model="formAcData.store_id"
              :filterable="true"
              :placeholder="t('device_manage.form.select_store_name')"
              style="width: 200px"
            >
              <el-option
                v-for="item in storeList"
                :key="item.id"
                :label="item.name"
                :value="item.id"
              />
            </el-select>
          </el-form-item>
        </el-form>
      </div>
      <template #footer_left>
        <el-button type="primary" link class="mt-[4px]" @click="addStoreForm">
          <FontIcon icon="icon-plus" />&nbsp;{{
            t("device_manage.form.add_store")
          }}
        </el-button>
      </template>
    </AuModal>

    <!--    新增门店弹窗-->
    <StoreModal
      ref="storeFormRef"
      v-model:showModal="showAddStorePopup"
      :is-modal="true"
      :showMinimize="false"
      :formData="storeFormData"
      @handleConfirm="handleStoreForm"
    />

    <AuModal
      v-model="showRecordPopup"
      :title="t('device_manage.form.activate_device')"
      width="70vw"
      height="60vh"
      :showConfirm="false"
      @handleConfirm="handleRecordConfirm"
    >
      <AuTable ref="tableRecordRef" v-bind="gridRecordOption" />
    </AuModal>
  </div>
</template>

<script setup lang="ts">
import { getCurrentInstance, h, nextTick, onMounted, reactive, ref } from "vue";
import { AuForm } from "@/components/AuForm";
import { AuTable } from "@/components/AuTable";
import { AuFormModal, AuModal } from "@/components/AuModal";
import { ObjectProps, PropDefines } from "@/components/AuTable/type";
import {
  deviceBindStoreId,
  deviceGetList,
  DeviceProp,
  updDeviceStatus,
  updStoreId
} from "@/api/teaInfuser/device";
import { getProvinceCity } from "@/api/user";
import {
  addStore,
  configAdd,
  configGetList,
  configUpd,
  getGroupList,
  getStoreList
} from "@/api/teaInfuser/store";
import { handleTree } from "@/utils/tree";
import { ElMessage, ElMessageBox } from "element-plus";
import { cloneDeep } from "lodash-unified";
import { storeGroupSelect } from "@/utils/formSelect";
import StoreModal from "@/views/teaInfuser/device/deviceManage/StoreModal.vue";
import { useRouter } from "vue-router";
import dayjs from "dayjs";
import { getReleaseSelect } from "@/api/teaInfuser/formula";
import { DEVICE_TYPE_LIST } from "@/utils/constants";
import { isNullOrUnDef } from "@pureadmin/utils";
import { useI18n } from "vue-i18n";
import { setDeviceTypeTrans } from "@/utils/tool";

const { t, te } = useI18n();

defineOptions({
  name: "FormulaDetail"
});

const { proxy } = getCurrentInstance();
const router = useRouter();

// region 页面及组件变量集合
const formList = ref([
  {
    type: "select",
    key: "device_type",
    label: "device_manage.form.device_type",
    labelKey: "label",
    valueKey: "value",
    placeholder: "device_manage.form.device_type_placeholder",
    emptyValues: [null, undefined],
    options: [
      { value: "", label: "device_manage.form.all_types" },
      ...DEVICE_TYPE_LIST
    ],
    defaultValue: ""
  },
  {
    type: "input",
    key: "device_id",
    label: "device_manage.form.device_code",
    placeholder: "device_manage.form.device_code_placeholder"
  },
  {
    type: "select",
    key: "device_status",
    label: "device_manage.form.device_status",
    labelKey: "label",
    valueKey: "value",
    columns: [],
    placeholder: "device_manage.form.device_status_placeholder",
    options: [
      {
        value: "2",
        label: "device_manage.form.not_activated"
      },
      {
        value: "0",
        label: "device_manage.form.normal"
      },
      {
        value: "1",
        label: "device_manage.form.locked"
      }
    ]
  },
  () => storeGroupSelect("group_id", {}, true)
]);

const cascadeProps = ref({
  placeholder: "device_manage.form.select_region",
  showAllLevels: true,
  filterable: true,
  props: {
    value: "id",
    label: "name",
    children: "children",
    emitPath: false,
    checkStrictly: true
  }
});

const formAcRule = ref({
  group_id: [
    {
      required: true,
      message: t("device_manage.form.select_region"),
      trigger: "change"
    }
  ],
  store_id: [
    {
      required: true,
      message: t("device_manage.form.select_store_name"),
      trigger: "change"
    }
  ]
});
const formAcRef = ref();

const formMoveData = ref({
  groupId: "",
  store_id: ""
});
const formAcData = ref({
  group_id: "",
  store_id: ""
});

const showAcPopup = ref(false);
const showAddStorePopup = ref(false);
const storeFormData = ref({
  group_id: null,
  id: ""
});

const activeFormatTime = ({ row }) => {
  const status = formatStatusText(row).status;
  if (status === "primary") {
    return row.activation_time;
  } else if (status === "info") {
    return "/";
  } else if (status === "danger") {
    return row.lock_time;
  }
};
const gridOption = reactive<PropDefines>({
  isServerPage: false,
  columns: [
    { field: "device_id", title: "device_manage.form.device_code" },
    {
      field: "device_type",
      width: 100,
      title: "device_manage.form.device_type",
      formatter({ row }) {
        return setDeviceTypeTrans(row.device_model, { te, t });
      }
    },
    {
      field: "store_name",
      title: "device_manage.form.store_name",
      showOverflow: false
    },
    {
      field: "device_status",
      title: "device_manage.form.device_status",
      width: 100,
      slots: { default: "status_default" },
      exportMethod({ row }) {
        return t(formatStatusText(row).text);
      }
    },
    {
      field: "activation_time",
      title: "device_manage.form.activation_lock_time",
      width: 180,
      formatter: activeFormatTime,
      exportMethod: activeFormatTime
    }
  ],
  actions: [],
  topTools: [
    {
      key: "lockRecord",
      name: "table.lockRecord",
      plain: true,
      onClick: () => {
        router.push({ name: "DeviceLockRecord", query: { status: 1 } });
      }
    }
  ],
  operateTools: [
    {
      icon: "material-symbols:move-item-sharp",
      key: "move",
      name: "table.telRelocation",
      hiddenHandle: (row: DeviceProp) =>
        !(row.device_status == 0 && row.store_id)
    },
    {
      icon: "material-symbols:lock-outline-sharp",
      key: "lock",
      name: "table.telLock",
      hiddenHandle: (row: DeviceProp) =>
        !(row.device_status == 0 && row.store_id)
    },
    {
      icon: "fluent-mdl2:account-activity",
      key: "activate",
      name: "table.activate",
      hiddenHandle: (row: DeviceProp) => row.store_id
    },
    {
      icon: "mingcute:unlock-line",
      key: "unlock",
      name: "table.unlock",
      hiddenHandle: (row: DeviceProp) =>
        !(row.device_status == 1 && row.store_id)
    }
  ],
  dataSource: [],
  fetchConfig: {
    query: {
      service: async (params: ObjectProps) => {
        const res = await deviceGetList(params);
        let data = res.data;
        if (params.status) {
          data = res.data.filter(v => !v.store_id);
        } else if (params.device_status == "0") {
          data = res.data.filter(v => v.device_status == 0 && v.store_id);
        }
        return {
          ...res,
          data: data,
          pageCount: data.length
        };
      },
      param: () => {
        const { group_id, ...rest } = formRef.value.getFormData();
        let group_idlist = [];
        if (group_id != null) {
          group_idlist = group_id.map((item: string) => ({
            group_id: item
          }));
        }
        if (rest.device_status === "2") {
          rest.device_status = null;
          rest.status = 1;
        }
        return {
          ...rest,
          group_idlist: JSON.stringify(group_idlist)
        };
      }
    }
  }
});
const rowData = ref<Partial<DeviceProp>>({});
const showMovePopup = ref(false);
const groupOptions = ref([]);
const storeList = ref([]);

const showRecordPopup = ref(false);
const gridRecordOption = reactive<PropDefines>({
  isServerPage: false,
  columns: [
    { field: "device_id", title: "device_manage.form.device_code" },
    { field: "store_name", title: "device_manage.form.store_name" },
    { field: "activation_time", title: "device_manage.form.activation_time" }
  ],
  dataSource: []
});

const provinceCity = ref([]);

let hasCalId = null;
let hasClearId = null;

const formRef = ref();
const formCalibrateRef = ref();
const storeFormRef = ref();
const tableRef = ref();
// endregion

// region 页面公共方法集合
type status = "success" | "warning" | "info" | "primary" | "danger";

function formatStatusText(row: DeviceProp): {
  text: string;
  status: status;
} {
  let text = "",
    status: status = "primary";
  if (row.device_status === 0 && row.store_id != null) {
    text = "device_manage.form.activated";
    status = "primary";
  } else if (row.store_id === null) {
    text = "device_manage.form.not_activated";
    status = "info";
  } else if (row.device_status === 1) {
    text = "device_manage.form.locked";
    status = "danger";
  }
  return {
    text,
    status
  };
}

function updateHandle(row: DeviceProp): {
  text: string;
  status: status;
} {
  let text = "",
    status: status = "success";
  const useTime = row.deviceFormulaUseRecord?.useTime;
  const releaseTime = row.releaseRecord?.releaseTime;
  if (!useTime) {
    text = "device_manage.form.not_updated";
    status = "info";
  } else if (dayjs(useTime).isAfter(dayjs(releaseTime))) {
    text = "device_manage.form.updated";
    status = "success";
  } else {
    text = "device_manage.form.not_updated";
    status = "info";
  }
  return {
    text,
    status
  };
}

const handleTreeNum = (tree: any[]) => {
  function traverse(node: {
    store_list: any[];
    children: any[];
    store_num: number;
    device_num: number;
    type: string;
    level: number;
  }) {
    let level = node.level ? node.level + 1 : 1;

    // 如果当前节点有store_list，累加长度
    if (node.store_list) {
      for (const store of node.store_list) {
        if (!node.children.find(item => item.id === store.id)) {
          node.children.unshift({
            id: store.id,
            name: store.name,
            expand: false,
            level: node.level ? node.level + 1 : 2
          });
        }
      }
    }

    // 递归处理子节点
    if (node.children && node.children.length > 0) {
      node.children.forEach(child => {
        level = traverse(child).level;
      });
    }

    // 添加store_num字段
    node.level = level;

    return { level };
  }

  // 遍历树结构
  tree.forEach(traverse);

  return tree;
};

const getMoveList = async () => {
  const res = await getReleaseSelect({});
  groupOptions.value = [{ id: "0", name: "全国", children: res.data }];
  getProvinceCity().then(res => {
    provinceCity.value = res.data;
  });
};

function handleLock(row: DeviceProp, type: number, note?: string) {
  const param = {
    idlist: JSON.stringify([{ id: row.id }]),
    device_status: type,
    note: note
  };
  updDeviceStatus(param).then(res => {
    ElMessage({
      message: t("device_manage.table.action_success", {
        action: type
          ? t("device_manage.form.lock")
          : t("device_manage.form.unlock")
      }),
      type: "success"
    });
    tableRef.value.refresh();
  });
}

async function getConfigParam() {
  const calRes = await configGetList({
    start_page: 1,
    size: 10,
    key: "min_calibration_interval",
    hiddenDeviceType: true
  });
  if (calRes.data.length) {
    const json = calRes.data[0].value;
    const { day } = JSON.parse(json);
    formCalibrateRef.value.setFormData({
      min_calibration_interval: day
    });
    hasCalId = calRes.data[0].id;
  }
  const clearRes = await configGetList({
    start_page: 1,
    size: 10,
    key: "min_clear_interval",
    hiddenDeviceType: true
  });
  if (clearRes.data.length) {
    const json = clearRes.data[0].value;
    const { day } = JSON.parse(json);
    formCalibrateRef.value.setFormData({
      min_clear_interval: day
    });
    hasClearId = clearRes.data[0].id;
  }
}

// endregion

// region 页面及组件事件集合
const saveCalibrate = () => {
  const calService = hasCalId ? configUpd : configAdd;
  const data = formCalibrateRef.value.getFormData();
  if (data.min_calibration_interval && data.min_calibration_interval > 0) {
    const param = {
      key: "min_calibration_interval",
      value: JSON.stringify({
        day: data.min_calibration_interval
      }),
      note: "最短校准周期",
      id: undefined
    };
    if (hasCalId) {
      param.id = hasCalId;
    }
    calService(param);
  }
  const clearService = hasClearId ? configUpd : configAdd;
  if (data.min_clear_interval && data.min_clear_interval > 0) {
    const param = {
      key: "min_clear_interval",
      value: JSON.stringify({
        day: data.min_clear_interval
      }),
      note: "最短清洗周期",
      id: undefined
    };
    if (hasClearId) {
      param.id = hasClearId;
    }
    clearService(param);
  }
};

const search = () => {
  tableRef.value.vxeGridRef.commitProxy("query");
};

const getChildrenIds = (tree, id) => {
  const result = [];
  const traverse = node => {
    if (node.id === id) {
      if (node.store_list) {
        node.store_list.forEach(store => {
          if (store.group_id) {
            result.push({ group_id: store.group_id });
          }
        });
      }
      if (node.children) {
        node.children.forEach(child => traverse(child));
      }
    } else {
      if (node.children) {
        node.children.forEach(child => traverse(child));
      }
    }
  };
  traverse(tree);
  return result;
};

/**
 * 根据指定ID查找节点及其所有子节点的ID
 * @param {Array} tree - 树结构数据
 * @param {Number} targetId - 目标节点ID
 * @return {Array<Object>} - 返回格式化的结果数组 [{group_id: val}, {group_id: val2}, ...]
 */
function findNodeAndChildren(tree: any[], targetId: number) {
  // 结果数组
  const result = [];

  /**
   * 递归查找节点
   * @param {Array|Object} nodes - 当前节点或节点数组
   * @param {Boolean} isFound - 是否已找到目标节点
   * @return {Boolean} - 是否找到目标节点
   */
  function traverse(nodes, isFound = false) {
    // 如果已经是数组，直接处理
    if (Array.isArray(nodes)) {
      for (const node of nodes) {
        if (traverse(node, isFound)) {
          return true;
        }
      }
      return false;
    }

    // 单个节点处理
    const node = nodes;

    // 如果找到目标节点或已经在目标节点的子树中
    if (node.id === targetId || isFound) {
      // 将当前节点添加到结果中
      result.push({ group_id: node.id });

      // 继续处理子节点
      if (node.children && node.children.length > 0) {
        traverse(node.children, true);
      }

      // 如果是目标节点本身，返回true表示已找到
      return node.id === targetId;
    }

    // 如果有子节点，递归查找
    if (node.children && node.children.length > 0) {
      if (traverse(node.children, false)) {
        return true;
      }
    }

    return false;
  }

  // 开始查找
  traverse(tree);

  return result;
}

const handleMoveChange = async (val?: number) => {
  try {
    const groupList = findNodeAndChildren(groupOptions.value, val);
    console.log(groupList);
    const storeRes = await getStoreList({
      start_page: 1,
      size: 0,
      group_idlist: JSON.stringify(groupList)
    });
    storeList.value = storeRes.data;
  } catch (e) {
    storeList.value = [];
  }
};

const closeMovePopup = () => {
  showMovePopup.value = false;
};

const handleMoveConfirm = () => {
  if (formMoveData.value.groupId && formMoveData.value.store_id) {
    updStoreId({
      idlist: JSON.stringify([{ device_id: rowData.value.device_id }]),
      store_id: formMoveData.value.store_id
    }).then(res => {
      closeMovePopup();
      closeMove();
      ElMessage({
        message: t("device_manage.table.action_success", {
          action: t("table.telRelocation")
        }),
        type: "success"
      });
      tableRef.value.vxeGridRef.commitProxy("query");
    });
  } else {
    ElMessage({
      message: t("device_manage.form.select_group_store"),
      type: "warning"
    });
  }
};

const handleAcConfirm = () => {
  formAcRef.value.validate((valid, fields) => {
    if (valid) {
      deviceBindStoreId({
        idlist: JSON.stringify([{ device_id: rowData.value.device_id }]),
        store_id: formAcData.value.store_id
      }).then(res => {
        ElMessage({
          message: t("device_manage.form.activation_success"),
          type: "success"
        });
        showAcPopup.value = false;
        tableRef.value.refresh();
      });
    } else {
      console.log("error submit!", fields);
    }
  });
};

const closeAc = () => {
  formAcData.value = {
    store_id: "",
    group_id: ""
  };
  formAcRef.value.resetFields();
};

const closeMove = () => {
  formMoveData.value = {
    groupId: "",
    store_id: ""
  };
};

const handleRecordConfirm = () => {
  showRecordPopup.value = false;
};

const addStoreForm = () => {
  showAddStorePopup.value = true;

  nextTick(() => {
    storeFormRef.value.getList();
  });
};

const handleStoreForm = (data: Record<string, string | number>) => {
  const _data = cloneDeep(data);
  if (!_data.group_id) {
    _data.group_id = 0;
  }
  addStore(_data).then(async res => {
    if (res.data == 0) {
      ElMessage({
        message: t("store_manage.form.has_store_warning"),
        type: "error"
      });
      return;
    }
    ElMessage({
      message: t("store_manage.form.add_success"),
      type: "success"
    });
    storeFormData.value = res.data;
    await handleMoveChange(Number(_data.group_id));
    if (_data.group_id == 0) {
      storeFormData.value.group_id = null;
    } else {
      formAcData.value.group_id = storeFormData.value.group_id;
    }
    formAcData.value.store_id = storeFormData.value.id;
    showAddStorePopup.value = false;
  });
};

const actionClick = ({ key, row }: { key: string; row: DeviceProp }) => {
  rowData.value = row;
  switch (key) {
    case "move":
      showMovePopup.value = true;
      break;
    case "activate":
      showAcPopup.value = true;
      break;
    case "lock":
    case "unlock":
      {
        let status = t("device_manage.form.activate");
        let type = 0;
        if (!row.store_id) {
          status = t("device_manage.form.activate");
          type = 0;
        }
        if (row.device_status == 0) {
          status = t("device_manage.form.lock");
          type = 1;
        }
        if (row.device_status == 1) {
          status = t("device_manage.form.unlock");
          type = 0;
        }
        proxy.$auMessageBox
          .confirm(
            t("device_manage.form.confirm_action", {
              action: status,
              device: row.device_id
            }),
            t("notice.title")
          )
          .then(() => {
            if (type === 0) {
              handleLock(row, type, "");
            } else {
              proxy.$auMessageBox
                .prompt(
                  t("device_manage.form.lock_reason"),
                  t("notice.title"),
                  {
                    inputPlaceholder: t(
                      "device_manage.form.enter_lock_reason_title"
                    ),
                    inputValidator: (value: string) => {
                      return !(!value || value?.trim() === "");
                    },
                    inputErrorMessage: t(
                      "device_manage.form.lock_reason_required"
                    )
                  }
                )
                .then(data => {
                  handleLock(row, type, data.value);
                });
            }
          });
      }
      break;
    default:
      break;
  }
};

onMounted(() => {
  getMoveList();
});

// endregion
</script>

<style lang="scss" scoped>
.active-wrap {
  :deep(.el-descriptions) {
    width: 280px;
    margin: 0 auto;

    .el-descriptions__body .el-descriptions__table:not(.is-bordered) {
      & tr:last-child {
        .el-descriptions__cell {
          padding-bottom: 0;
        }
      }

      .el-descriptions__cell {
        padding-bottom: 20px;
      }
    }
  }
}
</style>
